package e2e

import (
	"bytes"
	"encoding/json"
	"net/http/httptest"
	"net/url"

	"github.com/gin-gonic/gin"
)

type Request struct {
	Method string            // GET, POST, PUT, PATCH, DELETE
	Path   string            // /api/v1/users
	Body   any               // json body
	Query  map[string]string // query string
	Header map[string]string // header 默认 Content-Type: application/json
}

func JSONRequest(server *gin.Engine, request *Request) *httptest.ResponseRecorder {
	respRecorder := httptest.NewRecorder()

	encodedBody, err := json.Marshal(request.Body)
	if err != nil {
		panic(err)
	}

	if len(request.Query) != 0 {
		values := url.Values{}
		for key, value := range request.Query {
			if value != "" {
				values.Add(key, value)
			}
		}
		request.Path = request.Path + "?" + values.Encode()
	}

	req := httptest.NewRequest(request.Method, request.Path, bytes.NewReader(encodedBody))
	req.Header.Set("Content-Type", "application/json")
	for key, value := range request.Header {
		req.Header.Set(key, value)
	}

	server.ServeHTTP(respRecorder, req)
	return respRecorder
}

func JSONBodyParser[T any](resp *httptest.ResponseRecorder) *T {
	var target T
	err := json.Unmarshal(resp.Body.Bytes(), &target)
	if err != nil {
		panic(err)
	}
	return &target
}
